﻿using System; 
using System.Collections.Generic;
using System.Reflection;
using UnityEditor; 
using UnityEngine;

namespace XFGameFramework.ScriptableObjectSystem
{

    [CustomEditor(typeof(ScriptableObjectData), true)]
    public class ScriptableObjectDataInspector : Editor
    {

        private static ScriptableObjectDataInspector _instance;

        public static ScriptableObjectDataInspector Instance
        {
            get
            {
                if (_instance == null)
                    _instance = CreateInstance<ScriptableObjectDataInspector>();
                return _instance;
            }
        }

        private ScriptableObjectData currentScriptableObjectData;
        //private Type currentSkillConfigDataType; 
        private SerializedObject currentSerializedObject; 
        private List<SerializedProperty> currentSerializeProperty; 
        //private Vector2 currentPosition;
       
        private Dictionary<string,CustomPropertyGUI> custom_property = new Dictionary<string,CustomPropertyGUI>();

        private SerializedProperty script = null;

        public override void OnInspectorGUI()
        {
            EditorGUI.BeginDisabledGroup(true);

            base.OnInspectorGUI();

            EditorGUI.EndDisabledGroup();

            //if (GUILayout.Button("编辑"))
            //{
            //    ConfigsWindow window = EditorWindow.GetWindow<ConfigsWindow>();
            //    window.Show(); 
            //    window.RefreshCurrentConfig(currentScriptableObjectData);
            //}
        }

        internal void OnInspectorGUI(ScriptableObjectData data, ConfigsWindow window,ScriptableObjectConfigs configs )
        {  
            if (data != null)
            {
                if (currentScriptableObjectData != data)
                {
                    currentScriptableObjectData = data;
                    currentSerializedObject = null;  
                    //currentSkillConfigDataType = currentSkillConfigData.GetType();
                    custom_property.Clear(); 
                }

                if (currentSerializedObject == null)
                {
                    currentSerializedObject = new SerializedObject(currentScriptableObjectData);
                    script = currentSerializedObject.FindProperty("m_Script");
                    currentSerializeProperty = currentSerializedObject.GetAllSerializedProperty();
                }

                currentSerializedObject.Update();

                window.rightScrollPosition = GUILayout.BeginScrollView(window.rightScrollPosition);
                EditorGUI.BeginDisabledGroup(true);
                EditorGUILayout.PropertyField(script);
                EditorGUI.EndDisabledGroup();

                for (int i = 0; i < currentSerializeProperty.Count; i++)
                {
                    SerializedProperty property = currentSerializeProperty[i];

                    if (property.name == "parent" && property.objectReferenceValue == null)
                    {
                        property.objectReferenceValue = configs;
                    }

                    if (GetPropertyCustomAttribute<HideInInspector>(property) != null) continue;
                    CustomPropertyGUI customPropertyGUI = GetPropertyCustomAttribute<CustomPropertyGUI>(property);
                    EditorGUI.BeginChangeCheck();

                    if (customPropertyGUI != null)
                    {
                        customPropertyGUI.OnPropertyGUI(property);
                    }
                    else
                    {
                        EditorGUILayout.PropertyField(property);
                    }

                    if (EditorGUI.EndChangeCheck())
                    {
                        currentSerializedObject.ApplyModifiedProperties();

                        if (property.name == "id")
                            window.SetSelection(property.intValue);

                        //EditorUtility.SetDirty(currentSkillConfigData);

                        if (currentScriptableObjectData.parent != null)
                            currentScriptableObjectData.parent.ClearCache();

                        if (customPropertyGUI != null && customPropertyGUI.reloadTreeViewOnValueChange)
                            window.scriptableObjectListTree.Reload();
                    }
                }

                GUILayout.EndScrollView(); 
            }
            else
            {
                GUILayout.FlexibleSpace();
                EditorGUILayout.BeginHorizontal();
                GUILayout.FlexibleSpace();
                GUILayout.Label("空!");
                GUILayout.FlexibleSpace();
                EditorGUILayout.EndHorizontal();
                GUILayout.FlexibleSpace();
            }
        }


        private Dictionary<SerializedProperty, Dictionary<Type, Attribute>> attributes = new Dictionary<SerializedProperty, Dictionary<Type, Attribute>>();

        private T GetPropertyCustomAttribute<T>(SerializedProperty property) where T : Attribute
        {
            if (!attributes.ContainsKey(property))
                attributes.Add(property, new Dictionary<Type, Attribute>());

            if (attributes[property].ContainsKey(typeof(T)))
                return attributes[property][typeof(T)] as T;

            Type type = property.serializedObject.targetObject.GetType();
            FieldInfo fieldInfo = type.GetField(property.name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
            T customPropertyGUI = fieldInfo.GetCustomAttribute<T>();

            attributes[property].Add(typeof(T), customPropertyGUI);
            return customPropertyGUI;
        }
    }

}

